﻿/*Reg读写Panel*/
/*To do：更换十六进制控件*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using Sunny.UI;
using NovoDataBase;
using NovoSerDes;
using Sunny.UI.Win32;
using NovoSerDes.Funcs;

namespace NovoSerDesEva
{
    public partial class RegWriteReadPanel : UIPanel
    {
        SerDesComm commDev;
        NumericUpDown numericUpDown_ChipAddr;
        UIComboBox uiComboBox_IICMode;

        private USBDeviceMeditor usbDeveiceMetor;
        public USBDeviceMeditor UsbDeviceMetor
        {
            get { return usbDeveiceMetor; }
            set
            {
                usbDeveiceMetor = value;
                usbDeveiceMetor.USBDeviceChanged += usbDevice_DeviceChange;
            }
        }

        private void usbDevice_DeviceChange(object sender, SerDesComm newSerdesComm)
        {
            this.commDev = newSerdesComm;
        }
        public RegWriteReadPanel(SerDesComm _commDev, NumericUpDown _numericUpDown_ChipAddr, UIComboBox _uiComboBox_IICMode)
        {
            InitializeComponent();
            uiCheckBox_16bit.Checked = false;
            uiCheckBox_32bit.Checked = true;
            uiCheckBox_8bit.Checked = false;
            JudgeMaxMin();
            commDev = _commDev;
            if(commDev == null)
            {
                commDev = new SerDesComm();
                commDev.OpenDevice(0);
            }
            numericUpDown_ChipAddr = _numericUpDown_ChipAddr;
            uiComboBox_IICMode = _uiComboBox_IICMode;
            DpiSet();
            this.uiComboBox_IICMode.SelectedIndexChanged += new System.EventHandler(this.uiComboBox_IICMode_SelectedIndexChanged);
            JudgeAddressMax();
        }

        //别的文件（父页面）要想访问到这个文件（子页面）里的类的控件，需要定义一些公共属性和接口（后面没有括号的是属性，有括号的是方法）
        //别的文件实例化对象后可用这些属性和接口
        public int DecValue
        {
            get { return this.uiIntegerUpDown_DecValue.Value; }
            set { this.uiIntegerUpDown_DecValue.Value = value; }
        }

        public uint DecValue1
        {
            get { return this.cusUIUintUpDown_DecValue.Value; }
            set { this.cusUIUintUpDown_DecValue.Value = value; }
        }

        public int RegAddr
        {
            get { return (int)numericUpDown_RegAddress.Value; }
            set { numericUpDown_RegAddress.Value = value; }
        }

        public void RegRead()
        {
            byte _chipAddr = (byte)(numericUpDown_ChipAddr.Value * 2);
            IICMode _iicMode = IICModeDecode(uiComboBox_IICMode.SelectedItem.ToString());
            int byteCnt_RegAddr = ((byte)_iicMode >> 4) & 0x0F;
            int byteCnt_RegData = ((byte)_iicMode & 0x0F);

            object regAddr = this.numericUpDown_RegAddress.Value;

            object rdData = 0;
            bool ret = commDev.IICRead(_chipAddr, (object)regAddr, out rdData, _iicMode);
            if (ret)
            {
                this.uiIntegerUpDown_DecValue.Value = 0;
                this.uiIntegerUpDown_DecValue.Value = 1;
                //this.uiIntegerUpDown_DecValue.Value = Convert.ToInt32(rdData);
                this.cusUIUintUpDown_DecValue.Value = 0;
                this.cusUIUintUpDown_DecValue.Value = 1;
                this.cusUIUintUpDown_DecValue.Value = Convert.ToUInt32(rdData);
                //PrintInfo(String.Format("IIC Read, Reg:0x{0} = 0x{1}\r\n",
                //    (Convert.ToUInt32(regAddr)).ToString(String.Format("X{0}", 2 * byteCnt_RegAddr)),
                //    (Convert.ToUInt32(rdData)).ToString(String.Format("X{0}", 2 * byteCnt_RegData))));
            }
            else
                UIMessageDialog.ShowMessageDialog("IIC Read Failed!", "Error", showCancelButton: false, UIStyle.Red, showMask: false);
        }

        public void RegWrite()
        {
            byte _chipAddr = (byte)(this.numericUpDown_ChipAddr.Value * 2);
            IICMode _iicMode = IICModeDecode(this.uiComboBox_IICMode.SelectedItem.ToString());
            int byteCnt_RegAddr = ((byte)_iicMode >> 4) & 0x0F;
            int byteCnt_RegData = ((byte)_iicMode & 0x0F);

            object regAddr = this.numericUpDown_RegAddress.Value;
            //object regData = this.uiIntegerUpDown_DecValue.Value;
            object regData = this.cusUIUintUpDown_DecValue.Value;

            bool ret = commDev.IICWrite(_chipAddr, regAddr, regData, _iicMode);
            if (ret)
            {
                //PrintInfo(String.Format("IIC Read, Reg:0x{0} = 0x{1}\r\n",
                //    (Convert.ToUInt32(regAddr)).ToString(String.Format("X{0}", 2 * byteCnt_RegAddr)),
                //    (Convert.ToUInt32(regData)).ToString(String.Format("X{0}", 2 * byteCnt_RegData))));
            }
            else
                UIMessageDialog.ShowMessageDialog("IIC Write Failed!", "Error", showCancelButton: false, UIStyle.Red, showMask: false);
        }

        private IICMode IICModeDecode(string msg)
        {
            IICMode i2cMode = IICMode.A16D32;
            if (Enum.TryParse(msg.ToUpper(), true, out i2cMode))
                return i2cMode;
            else
                return IICMode.None;
        }

        /*限制十六进制文本框输入*/
        private void uiTextBox_HexValue1_KeyPress(object sender, KeyPressEventArgs e)
        {
            // 允许输入的字符（0-9和A-F），以及退格键
            if (!char.IsControl(e.KeyChar) && !((e.KeyChar >= '0' && e.KeyChar <= '9') || (e.KeyChar >= 'A' && e.KeyChar <= 'F')))
            {
                // 如果输入的字符不是十六进制数字，则阻止输入
                e.Handled = true;
            }
            // 获取当前文本框中的文本
            string currentText = uiTextBox_HexValue.Text;

            // 根据CheckBox状态决定限制的字符数量
            int maxCharacters = 4;
            if (uiCheckBox_8bit.Checked)
            {
                maxCharacters = 2;
            }
            else if (uiCheckBox_16bit.Checked)
            {
                maxCharacters = 4;
            }
            else if (uiCheckBox_32bit.Checked)
            {
                maxCharacters = 8;
            }

            // 如果当前文本框中已有N个及以上个字符，并且用户不是在替换选中文本，并且不是退格键，则阻止输入
            if (currentText.Length == maxCharacters && uiTextBox_HexValue.SelectionLength == 0 && e.KeyChar != '\b')
            {
                e.Handled = true;
            }
        }

        /*十六进制文本转十进制*/
        private void uiTextBox_HexValue1_TextChanged(object sender, EventArgs e)
        {
            // 获取文本框中的十六进制值
            string hexValue = uiTextBox_HexValue.Text.Trim();

            // 将十六进制值转换为整数值
            if (int.TryParse(hexValue, System.Globalization.NumberStyles.HexNumber, null, out int intValue))
            {
                // 更新整数上下按钮的值
                uiIntegerUpDown_DecValue.Value = intValue;
                UpdateCheckBoxGroup(intValue);
            }

            if (uint.TryParse(hexValue, System.Globalization.NumberStyles.HexNumber, null, out uint uintValue))
            {
                // 更新整数上下按钮的值
                cusUIUintUpDown_DecValue.Value = uintValue;
                //UpdateCheckBoxGroup1(uintValue);
            }
        }

        /*十进制转十六进制文本*/
        private void uiIntegerUpDown_DecValue_ValueChanged(object sender, int value)
        {
            //获取整数上下按钮的值
            int intValue = (int)uiIntegerUpDown_DecValue.Value;

            //将整数值转换为十六进制字符串
            string hexValue = intValue.ToString("X");

            //更新十六进制文本框的值
            uiTextBox_HexValue.Text = hexValue;
        }

        private void cusUIUintUpDown_DecValue_ValueChanged(object sender, decimal value)
        {
            //获取整数上下按钮的值
            uint uintValue = (uint)cusUIUintUpDown_DecValue.Value;

            //将整数值转换为十六进制字符串
            string hexValue = uintValue.ToString("X");

            //更新十六进制文本框的值
            uiTextBox_HexValue.Text = hexValue;
        }

        /*十六进制文本加1按键*/
        private void uiSymbolButton_AddHex_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(uiTextBox_HexValue.Text))
            {
                // 获取当前文本框中的十六进制值
                string hexValue = uiTextBox_HexValue.Text.Trim();

                // 将十六进制字符串转换为整数
                //if (int.TryParse(hexValue, System.Globalization.NumberStyles.HexNumber, null, out int intValue))
                //{
                //    // 检查是否已达到最大值
                //    if (intValue < uiIntegerUpDown_DecValue.Maximum)
                //    {
                //        // 增加十六进制值
                //        intValue++;

                //        // 更新文本框中的值为增加后的十六进制值
                //        uiTextBox_HexValue.Text = intValue.ToString("X");
                //    }
                //}

                if (uint.TryParse(hexValue, System.Globalization.NumberStyles.HexNumber, null, out uint uintValue))
                {
                    // 检查是否已达到最大值
                    if (uintValue < cusUIUintUpDown_DecValue.Maximum)
                    {
                        // 增加十六进制值
                        uintValue++;

                        // 更新文本框中的值为增加后的十六进制值
                        uiTextBox_HexValue.Text = uintValue.ToString("X");
                    }
                }
            }
        }

        /*十六进制文本减1按键*/
        private void uiSymbolButton_SubHex_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(uiTextBox_HexValue.Text))
            {
                // 获取当前文本框中的十六进制值
                string hexValue = uiTextBox_HexValue.Text.Trim();

                // 将十六进制字符串转换为整数
                //if (int.TryParse(hexValue, System.Globalization.NumberStyles.HexNumber, null, out int intValue))
                //{
                //    if (intValue > uiIntegerUpDown_DecValue.Minimum)
                //    {
                //        // 减少十六进制值
                //        intValue--;

                //        // 更新文本框中的值为减少后的十六进制值
                //        uiTextBox_HexValue.Text = intValue.ToString("X");
                //    }

                //}

                if (uint.TryParse(hexValue, System.Globalization.NumberStyles.HexNumber, null, out uint uintValue))
                {
                    if (uintValue > cusUIUintUpDown_DecValue.Minimum)
                    {
                        // 减少十六进制值
                        uintValue--;

                        // 更新文本框中的值为减少后的十六进制值
                        uiTextBox_HexValue.Text = uintValue.ToString("X");
                    }

                }
            }
        }

        /*16bit、32bit和8bit复选框*/
        private void uiCheckBox_16bit_CheckedChanged(object sender, EventArgs e)
        {
            if (uiCheckBox_16bit.Checked)
            {
                uiCheckBox_32bit.Checked = false;
                uiCheckBox_8bit.Checked = false;
            }
            else if (!uiCheckBox_32bit.Checked && !uiCheckBox_8bit.Checked)  // 如果三个复选框都不被选中，则选中 uiCheckBox_16bit
            {
                uiCheckBox_16bit.Checked = true;
            }
            JudgeMaxMin();
            SetGroupBitChoice(16);
        }
        private void uiCheckBox_32bit_CheckedChanged(object sender, EventArgs e)
        {
            if (uiCheckBox_32bit.Checked)
            {
                uiCheckBox_16bit.Checked = false;
                uiCheckBox_8bit.Checked = false;
            }
            else if (!uiCheckBox_16bit.Checked && !uiCheckBox_8bit.Checked)  // 如果三个复选框都不被选中，则选中 uiCheckBox_32bit
            {
                uiCheckBox_32bit.Checked = true;
            }
            JudgeMaxMin();
            SetGroupBitChoice(32);
        }
        private void uiCheckBox_8bit_CheckedChanged(object sender, EventArgs e)
        {
            if (uiCheckBox_8bit.Checked)
            {
                uiCheckBox_16bit.Checked = false;
                uiCheckBox_32bit.Checked = false;
            }
            else if (!uiCheckBox_16bit.Checked && !uiCheckBox_32bit.Checked) // 如果两个复选框都不被选中，则选中 uiCheckBox_8bit
            {
                uiCheckBox_8bit.Checked = true;
            }
            JudgeMaxMin();
            SetGroupBitChoice(8);
        }

        /*判断16bit、32bit和8bit时最大值和最小值*/
        public void JudgeMaxMin()
        {
            if (uiCheckBox_16bit.Checked)
            {
                uiIntegerUpDown_DecValue.Maximum = 65535;
                uiIntegerUpDown_DecValue.Minimum = 0;
                cusUIUintUpDown_DecValue.Maximum = 65535;
                cusUIUintUpDown_DecValue.Minimum = 0;
            }
            else if (uiCheckBox_32bit.Checked)
            {
                uiIntegerUpDown_DecValue.Maximum = Int32.MaxValue;
                uiIntegerUpDown_DecValue.Minimum = Int32.MinValue;
                cusUIUintUpDown_DecValue.Maximum = UInt32.MaxValue;
                cusUIUintUpDown_DecValue.Minimum = 0;
            }
            else if (uiCheckBox_8bit.Checked)
            {
                uiIntegerUpDown_DecValue.Maximum = 255;
                uiIntegerUpDown_DecValue.Minimum = 0;
                cusUIUintUpDown_DecValue.Maximum = 255;
                cusUIUintUpDown_DecValue.Minimum = 0;
            }
        }

        /*选择不同bit位时，更新uiCheckBoxGroup_BitChoice数组的个数*/
        private void SetGroupBitChoice(int bits)
        {
            this.uiCheckBoxGroup_BitChoice.Items.Clear();

            // 根据传入的位数添加相应的选项
            for (int i = bits - 1; i >= 0; i--)
            {
                this.uiCheckBoxGroup_BitChoice.Items.Add(i.ToString());
            }
        }

        /*更新uiCheckBoxGroup_BitChoice，我的uiCheckBoxGroup_BitChoice[i]数组是颠倒的*/
        private void UpdateCheckBoxGroup(int intValue)
        {
            for (int i = 0; i < uiCheckBoxGroup_BitChoice.Items.Count; i++)
            {
                //int bitValue = 1 << i;
                int bitValue = 1 << (uiCheckBoxGroup_BitChoice.Items.Count - 1 - i);
                uiCheckBoxGroup_BitChoice[i] = (intValue & bitValue) == bitValue;
            }
        }

        private void UpdateCheckBoxGroup1(uint uintValue)
        {
            for (int i = 0; i < uiCheckBoxGroup_BitChoice.Items.Count; i++)
            {
                //int bitValue = 1 << i;
                int bitValue = 1 << (uiCheckBoxGroup_BitChoice.Items.Count - 1 - i);
                uiCheckBoxGroup_BitChoice[i] = (uintValue & bitValue) == bitValue;
            }
        }

        /*uiCheckBoxGroup_BitChoice的值改变时，更新十六进制文本和十进制值*/
        private void uiCheckBoxGroup_BitChoice_ValueChanged(object sender, CheckBoxGroupEventArgs e)
        {
            // 初始化整数值为0
            int intValue = 0;

            // 遍历复选框组中的所有复选框，从最后一个到第一个
            for (int i = uiCheckBoxGroup_BitChoice.Items.Count - 1; i >= 0; i--)
            {
                bool isChecked = uiCheckBoxGroup_BitChoice[i];
                // 如果复选框被选中，则将对应位设置为1
                if (isChecked)
                {
                    intValue |= (1 << (uiCheckBoxGroup_BitChoice.Items.Count - 1 - i)); // 反向计算索引
                }
            }
            // 更新整数上下按钮的值
            uiIntegerUpDown_DecValue.Value = intValue;
            // 设置光标位置到文本的末尾(解决加入复选框组值改变事件时，在uiTextBox_HexValue.Text输入时光标会前置的问题)
            uiTextBox_HexValue.SelectionStart = uiTextBox_HexValue.Text.Length;
        }

        private void uiSymbolButton_RegRead_Click(object sender, EventArgs e)
        {
            RegRead();
        }

        private void uiSymbolButton_RegWrite_Click(object sender, EventArgs e)
        {
            RegWrite();
        }

        private void numericUpDown_RegAddress_ValueChanged(object sender, EventArgs e)
        {
            // 检查值是否为4的整数倍
            int value = (int)numericUpDown_RegAddress.Value;
            //if (value % 4 != 0)
            //{
            //    // 如果值不是4的整数倍，则将其设置为最接近的4的整数倍
            //    int newValue = (value / 4) * 4; // 取整
            //    numericUpDown_RegAddress.Value = newValue;
            //    UIMessageDialog.ShowMessageDialog("寄存器地址必须是4的整数倍!", "Reg Address Warning", showCancelButton: false, UIStyle.Orange, showMask: false);
            //}
            if (value % 1 != 0)
            {
                // 如果值不是1的整数倍，则将其设置为最接近的1的整数倍
                int newValue = (value / 1) * 1; // 取整
                numericUpDown_RegAddress.Value = newValue;
                UIMessageDialog.ShowMessageDialog("寄存器地址必须是1的整数倍!", "Reg Address Warning", showCancelButton: false, UIStyle.Orange, showMask: false);
            }
        }

        private float GetDPI()
        {
            using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
            {
                float dpiX = graphics.DpiX;
                float dpiY = graphics.DpiY;
                return dpiX;
            }
        }

        private void DpiSet()
        {
            double dpi = GetDPI();
            double scale = dpi / 0.96;
            if (scale == 150 || scale == 125) //100% - 96 DPI;125% - 120 DPI;150% - 144 DPI;175% - 168 DPI;200% - 192 DPI
            {
                foreach (Control control in this.Controls)
                {
                    // 检查控件是否有Font属性，并且是否支持更改  
                    if (control.Font != null)
                    {
                        control.Font = new System.Drawing.Font("宋体", 9F);
                    }
                }
            }
        }

        private void uiComboBox_IICMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            JudgeAddressMax();
        }

        private void JudgeAddressMax()
        {
            IICMode _iicMode = IICModeDecode(this.uiComboBox_IICMode.SelectedItem.ToString());
            int bitwidth_RegAddr = (((byte)_iicMode >> 4) & 0x0F) * 8;
            int bitwidth_RegData = ((byte)_iicMode & 0x0F) * 8;

            this.numericUpDown_RegAddress.Maximum = (Decimal)Math.Pow(2, bitwidth_RegAddr) - 1;
            //Console.WriteLine(((uint)this.numericUpDown_RegAddress.Maximum).ToString("X"));
            //this.numUD_RegData.Maximum = (Decimal)Math.Pow(2, bitwidth_RegData) - 1;
        }
    }
}
